package com.controller;

import com.config.NewConfigurator;
import com.config.WebSocketDecoder;
import com.config.WebSocketEncoder;
import com.model.FrontUser;
import com.model.response.Request;
import com.model.response.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/socket", configurator = NewConfigurator.class, encoders = {WebSocketEncoder.class}, decoders = {WebSocketDecoder.class})
@Component
@Slf4j
public class WebSocket{

    private static ConcurrentHashMap<Long, WebSocket> webSocketMap = new ConcurrentHashMap<>();
    private Session session;
    private Long userId;
    private enum CODE {
        NULL;
        private static int PING = 1, PONG = 1;
        private static int NOT_LOGIN = -1;
    }
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) throws IOException, EncodeException {
        this.session = session;
        HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        FrontUser user = (FrontUser) httpSession.getAttribute("front_user");
        if(user == null) {
            this.sendMessage(new Response().setCode(CODE.NOT_LOGIN).setMsg("Not Login"));
            session.close();
            return;
        }


        this.userId = user.getId();
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
        }
        webSocketMap.put(userId,this);

        try {
            sendMessage(Response.success(user));
        } catch (IOException e) {
            log.error("用户:"+userId+",网络异常!!!!!!");
        } catch (EncodeException e) {
            log.error("Encode 异常");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if(userId != null && webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
        }
    }

    @OnMessage
    public void onMessage(Request request) throws IOException, EncodeException {
        if(request.getCode() == CODE.PING) {
            this.sendMessage(new Response().setCode(CODE.PONG).setMsg("ack"));
        }
    }

    public void sendMessage(Response message) throws IOException, EncodeException {
        this.session.getAsyncRemote().sendObject(message);
    }


    public static void sendMessage(Long userID, Response message) throws IOException, EncodeException {
        webSocketMap.get(userID).sendMessage(message);
    }


}
